package com.southwind.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.southwind.entity.OrderDetail;
import com.southwind.entity.OrderMaster;
import com.southwind.entity.ProductInfo;
import com.southwind.exception.ShopException;
import com.southwind.feign.ProductFeign;
import com.southwind.form.BuyerOrderForm;
import com.southwind.form.BuyerOrderItemForm;
import com.southwind.result.ResponseEnum;
import com.southwind.service.OrderDetailService;
import com.southwind.service.OrderMasterService;
import com.southwind.util.ResultVOUtil;
import com.southwind.vo.OrderMasterVO;
import com.southwind.vo.ResultVO;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单详情表 前端控制器
 * </p>
 *
 * @author southwind
 * @since 2023-12-30
 */
@RestController
@RequestMapping("/buyer/order")
public class BuyerOrderController {


    @Autowired
    private OrderMasterService orderMasterService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private ProductFeign productFeign;

    private RocketMQTemplate rocketMQTemplate;


    /**
     * todo 这有两个问题需要解决 1.主表插入数据时候崩了，怎么办  2.远程调用feign了，那边出现减库存异常了，之后怎么办
     *
     * @param orderForm
     * @return
     */
    @PostMapping("create")
    @Transactional
    public ResultVO create(@RequestBody BuyerOrderForm orderForm) {

        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setBuyerName(orderForm.getName());
        orderMaster.setBuyerPhone(orderForm.getPhone());
        orderMaster.setBuyerAddress(orderForm.getAddress());
        orderMaster.setBuyerOpenid(orderForm.getId());

        BigDecimal amount = new BigDecimal(0);
        // 订单详细
        for (BuyerOrderItemForm item : orderForm.getItems()) {

            // 根据id 获取这个商品的信息，计算出单价，之后这个单价计算出这个和 之后 加到一起
            // 这个就需要 调用product-service工程的接口了
            // 两个服务之见的调用，使用feign进行调用
            // 获取商品信息
            BigDecimal productPrice = productFeign.findPriceById(item.getProductId());
            BigDecimal price = productPrice.multiply(new BigDecimal(item.getProductQuantity()));
            // 计算总价
            amount = amount.add(price);
            // 在顺便一下 插入订单明细,不能插了，需要主表刚插入的id 这主表没插入呢
            // 主表的id 还没生成呢
        }
        orderMaster.setOrderAmount(amount);
        // 插入主表，这个orderMaster 会返回刚刚插入的id
        orderMasterService.save(orderMaster);

        // 创建订单 一个顾客可能有多个订单，一个订单中可能有多个商品
        // 有两个表 一个是主表，一个是从表
        // 主表插入一条，从表插入多条数据

        for (BuyerOrderItemForm item : orderForm.getItems()) {
            //插入订单详细

            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderMaster.getOrderId());
            orderDetail.setProductId(item.getProductId());
            orderDetail.setProductQuantity(item.getProductQuantity());
            ProductInfo productInfo = this.productFeign.findById(item.getProductId());
            orderDetail.setProductName(productInfo.getProductName());
            orderDetail.setProductIcon(productInfo.getProductIcon());
            orderDetail.setProductPrice(productInfo.getProductPrice());
            // 插入明细
            orderDetailService.save(orderDetail);

            // 减库存
            try {
                this.productFeign.subStock(item.getProductId(), item.getProductQuantity());
            } catch (Exception e) {
                throw new ShopException(ResponseEnum.PRODUCT_STOCK_ERROR.getMsg());
            }


        }
        Map<String, Object> map = new HashMap<>();
        map.put("orderId", orderMaster.getOrderId());


        // 存入mq
        rocketMQTemplate.convertAndSend("myTopic","有新的消息");

        return ResultVOUtil.success(map);

    }


    /**
     * 查询订单集合
     *
     * @param buyerId 购买者id
     * @param page    当前页
     * @param size    显示的条数
     * @return
     */
    @GetMapping("/list/{buyerId}/{page}/{size}")
    public ResultVO list(
            @PathVariable("buyerId") Integer buyerId,
            @PathVariable("page") Integer page,
            @PathVariable("size") Integer size
    ) {
        Page<OrderMaster> page1 = new Page<>(page, size);
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("buyer_openid", buyerId);
        Page<OrderMaster> page2 = this.orderMasterService.page(page1, queryWrapper);
        List<OrderMaster> records = page2.getRecords();
        return ResultVOUtil.success(records);
    }


    /**
     * @param buyerId 购买者id
     * @param orderId 订单id
     * @return
     */
    @GetMapping("/detail/{buyerId}/{orderId}")
    public ResultVO detail(
            @PathVariable("buyerId") Integer buyerId,
            @PathVariable("orderId") String orderId
    ) {
        // 根据 buyerId 和 orderId 查询出你这个订单购买了哪些东西
        // 封装一个 vo对象，里面装了订单 和 订单明细数据

        // 根据orderId和buyerId 查询主表数据

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id", orderId);
        OrderMaster orderMaster = orderMasterService.getOne(queryWrapper);
        // 根据 orderId 和 buyerId(购买者) 查询订单明细
        QueryWrapper<OrderDetail> orderDeatilWrapper = new QueryWrapper();
        orderDeatilWrapper.eq("order_id", orderId);
        List<OrderDetail> orderDetailList = orderDetailService.list(orderDeatilWrapper);

        OrderMasterVO orderMasterVO = new OrderMasterVO();

        BeanUtils.copyProperties(orderMaster, orderMasterVO);

        orderMasterVO.setOrderDetailList(orderDetailList);

        return ResultVOUtil.success(orderMasterVO);
    }


    /**
     * 取消订单的接口
     *
     * @param buyerId 购买者id
     * @param orderId 订单id
     * @return
     */
    @PutMapping("/cancel/{buyerId}/{orderId}")
    public ResultVO cancel(@PathVariable("buyerId") Integer buyerId,
                           @PathVariable("orderId") String orderId) {

        // 取消订单就是改变订单的状态把
        // 根据 orderId  和  buyerId 查询订单
        // 之后将状态修改为 取消
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("buyer_openid", buyerId);
        queryWrapper.eq("order_id", orderId);
        OrderMaster one = this.orderMasterService.getOne(queryWrapper);
        one.setOrderStatus(2); // 订单状态 订单状态，默认0新下单,1完成，2取消
        this.orderMasterService.updateById(one);
        return ResultVOUtil.success(null);

    }

    @PutMapping("/finish/{orderId}")
    public ResultVO finish(@PathVariable("orderId") String orderId) {
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderId);
        OrderMaster one = this.orderMasterService.getOne(queryWrapper);
        one.setOrderStatus(1); // 订单状态 订单状态，默认0新下单,1完成，2取消
        this.orderMasterService.updateById(one);
        return ResultVOUtil.success(null);
    }

    @PutMapping("/pay/{buyerId}/{orderId}")
    public ResultVO pay(@PathVariable("buyerId") Integer buyerId,
                        @PathVariable("orderId") String orderId) {
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("buyer_openid", buyerId);
        queryWrapper.eq("order_id", orderId);
        OrderMaster one = this.orderMasterService.getOne(queryWrapper);
        // payStatus ---支付状态 支付状态，默认0未支付，1已支付
        one.setOrderStatus(1);
        this.orderMasterService.updateById(one);
        return ResultVOUtil.success(null);
    }


}

